package processor;

import java.io.InputStream;
import java.util.Date;

import models.Doc;
import models.Doc.Category;
import models.Doc.Mandatory;
import models.DocFile;
import models.DocFile.ContentType;
import play.db.jpa.JPA;
import prefix.platform.Constants;
import prefix.util.FileUtil;
import prefix.util.FileUtil.DatePrecision;
import prefix.util.JPAUtil;
import repository.DocRepository;
import service.ActorService;
import service.DocService;
import service.LoanAppService;
import service.exception.DocException;
import service.exception.DocException.CODE;
import service.impl.DocServiceImpl;

public class DocProcessor extends DocServiceImpl {

    public DocProcessor(Doc doc) {
        super(doc);
    }

    public DocProcessor() {
    }

    public void  submitRequiredDoc(InputStream uploadFile, String originalFileName, ActorService docOwner,
            Doc.Type docType, ContentType contentType) throws Exception {
        try {
            JPAUtil.beginTransaction();
            Date now = new Date();
            DocService docService = DocRepository.getDocByType(docOwner.getDBActor().getId(), docType);
            LoanAppService loanApp = docOwner.getCurrentLoanApplication();
            if (docService == null) {
                DocService emptyDoc = docOwner.getApplicableBorrowerDocs(loanApp.getDBLoanApp().getLoanType()).get(
                        docType);
                this.dbdoc = emptyDoc.getDbdoc();
                this.dbdoc.setStatus(Doc.Status.UPLOADED);
                this.dbdoc.setStatusD(now);
                JPAUtil.em().persist(this.dbdoc);
            } else {
                if (Doc.Status.VERIFIED.equals(this.dbdoc.getStatus()))
                    throw new DocException(CODE.DISALLOW_UPLOAD_AFTER_VERIFIED);
                this.dbdoc.setStatus(Doc.Status.UPLOADED);
                this.dbdoc.setStatusD(now);
                JPAUtil.em().merge(this.dbdoc);
            }
            this.dbdoc.setAid(docOwner.getDBActor().getId());
            this.dbdoc.setLoanAppId(loanApp.getDBLoanApp().getId());
            DocFile docFile = new DocFile();
            String version = String.valueOf(now.getTime());
            String finalPath = "";
            String extension = "";

            // Get file name and extension from original name
            String[] parts = originalFileName.split("\\.");
            originalFileName = originalFileName.replaceAll("\\.\\w+$", "");
            extension = parts[parts.length - 1];
            int i = 1;
            // Make sure the file name is unique
            while (finalPath == null || finalPath.equals("")) {
                // Generate file name
                String fileName = originalFileName + (i > 1 ? " (" + i + ")" : "") + "." + extension;
                finalPath = FileUtil.faststoreInputStreamToFile(uploadFile, Constants.BORROWERDOCSROOT
                        + docOwner.getDBActor().getId() + "/", fileName, DatePrecision.DAILY);
                i++;
            }
            docFile.setDocId(this.dbdoc.getId());
            docFile.setCreateD(now);
            this.dbdoc.setVersion(version);
            docFile.setLocation(finalPath);
            docFile.setProcessed(DocFile.ProcessStatus.NOT_PROCESSED);
            JPAUtil.em().persist(docFile);
            JPAUtil.commitTransaction();
        } catch (DocException e) {
            throw e;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            throw new DocException(CODE.UNKNOWN, e);
        } finally {
            JPAUtil.closeEM();
        }

    }

    public void updateRequiredDocStatus(ActorService docOwner, Doc.Type docType, Doc.Status status, Mandatory mandatory)
            throws DocException {
        try {
            JPAUtil.beginTransaction();
            if (this.getDbdoc().getId() != null) {
                this.dbdoc.setValues(status, mandatory);
                JPA.em().merge(this.dbdoc);
            } else {
                this.dbdoc.setupEmplyDoc(docOwner.getDBActor().getId(), docOwner.getCurrentLoanApplication()
                        .getDBLoanApp().getId(), status, mandatory, Category.BORROWER_DOCS, docType);
                JPA.em().persist(this.dbdoc);
            }
            JPAUtil.commitTransaction();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            throw new DocException(CODE.UNKNOWN, e);
        } finally {
            JPAUtil.closeEM();
        }

    }

}
